import re

from django.conf import settings
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from celery_tasks.email.tasks import send_verify_email
from users.models import User
from itsdangerous import TimedJSONWebSignatureSerializer as TJS


class UserSerialzier(serializers.ModelSerializer):
    password2 = serializers.CharField(max_length=20, min_length=8, write_only=True)
    sms_code = serializers.CharField(max_length=4, min_length=4, write_only=True)
    allow = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ["username", "mobile", "password", "password2", "sms_code", "allow", "id"]
        extra_kwargs = {
            'password': {
                "max_length": 20,
                "min_length": 8,
                "write_only": True
            },
            'username': {
                "max_length": 20,
                "min_length": 5,
            }
        }

    def validate_mobile(self, value):
        re_str = r"^1[0-13-9]\d{9}$"
        if not re.match(re_str, value):
            raise serializers.ValidationError("手机号格式不正确")
        return value

    def validate_allow(self, value):
        if value != "true":
            raise serializers.ValidationError("请同意用户协议")
        return value

    def validate(self, data):
        if re.match(r"^1[03-9]\d{9}$", data["username"]):
            if data['username'] != data['mobile']:
                raise serializers.ValidationError("手机号和用户名不一致")

        if data["password"] != data["password2"]:
            raise serializers.ValidationError("两次密码不匹配")

        redis_conn = get_redis_connection("sms_code")
        real_sms_code = redis_conn.get("sms_code_%s" % data["mobile"])

        if not real_sms_code:
            raise serializers.ValidationError("验证码失效")

        if real_sms_code.decode() != data["sms_code"]:
            print(real_sms_code)
            print(data["sms_code"])
            raise serializers.ValidationError("验证码错误")

        return data

    def create(self, validated_data):

        del validated_data["sms_code"]
        del validated_data["password2"]
        del validated_data["allow"]

        user = User.objects.create_user(**validated_data)

        # 补充生成记录登录状态的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        user.token = token

        return user


class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')


class UserEmailSerialzier(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("email",)

    def update(self, instance, validated_data):
        instance.email = validated_data["email"]
        instance.save()

        data = {
            'user_id': instance.id,
            'email': validated_data["email"]
        }

        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps(data).decode()
        to_email = validated_data['email']

        send_verify_email(token, to_email)

        return instance

class PasswordChange(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    password2 = serializers.CharField(write_only=True)
    old_password = serializers.CharField(write_only=True)
    class Meta:
        model = User
        fields = ("old_password","password","password2",)

    def validate_old_password(self,value):
        print("验证密码")
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("密码错误")

        print("验证密码成功")

        return value

    def validate(self, data):

        if data['password'] != data['password2']:
            raise serializers.ValidationError("两次新密码密码输入不一致")
        return data

    def update(self, instance, validated_data):
        print(instance)
        try:
            instance.set_password(validated_data['password'])
            instance.save()
        except Exception as e:
            print(e)
            raise serializers.ValidationError("修改密码失败")

        print(instance)
        return instance


